import {Component, createRef} from "react";
import {Col, Form, Row, Table, Button, FormInstance, AutoComplete, Space, Typography, Popconfirm, message, Modal, Input, Spin, Divider} from "antd";


import {ColumnsType, TablePaginationConfig} from "antd/es/table";

import {URL, send} from '../../../utils/http.util.tsx'
import {randomString, PageUtil, DEFAULT_PAGINATION, Handler} from '../../../utils/util.tsx'

import LazyIcon from "../../../components/Tools/Icon";

const {Link} = Typography;

import {Data, State} from './types.tsx'
import {isAdmin} from "../../../utils/auth.util.tsx";

class Admin extends Component<any, State> {
    searchFormRef = createRef<FormInstance>()
    adminAddingFormRef = createRef<FormInstance>()
    adminModifyingFormRef = createRef<FormInstance>()
    secretResettingFormRef = createRef<FormInstance>()

    columns: ColumnsType<Data> = [
        {
            title: '管理员 ID',
            dataIndex: 'id',
            key: 'id',
        },
        {
            title: '登录名',
            dataIndex: 'name',
            key: 'name',
        },
        {
            title: '昵称',
            dataIndex: 'nickname',
            key: 'nickname',
        },
        {
            title: '操作',
            dataIndex: 'ops',
            key: 'ops',
            render: (_, record) => (
                <>
                    <Space size="middle">
                        <Link type={"warning"} onClick={() => this.setState({id: record.id, secretResettingModalVisible: true})}>重置密码</Link>
                        <Link onClick={() => this.setState({id: record.id, name: record.name, nickname: record.nickname, adminModifyingModalVisible: true})}>修改</Link>
                    </Space>
                    <Divider type="vertical"/>
                    <Popconfirm title={`确认删除「${record.nickname}」？`} onConfirm={() => this.handleDelete(record)} okText="确认" cancelText="取消">
                        <Link type={"danger"}>删除</Link>
                    </Popconfirm>
                </>
            )
        }
    ]

    state = {
        data: [],
        states: [],
        pagination: DEFAULT_PAGINATION,
        loading: true,

        optionsOfCreateBy: [], // CreateBy AutoComplete 组件的 options

        id: null,
        name: '',
        nickname: '',
        secretResettingModalVisible: false, adminAddingModalVisible: false, adminModifyingModalVisible: false
    }

    componentDidMount() {
        this.handleFetch();

        send(URL.states).then((resp) => {
            const httpCode = resp.data.httpCode;
            if (httpCode === 200) {
                const data = resp.data.data;
                this.setState({states: data})
            } else Handler.ofHttpWarn(httpCode)
        }).catch(Handler.ofError)
    }

    handleFetch(qo: any = undefined, pagination: TablePaginationConfig | undefined = undefined) {
        this.setState({loading: true})

        if (qo) {
            if (qo.createTimeArr) {
                qo.createTimeStart = qo.createTimeArr[0].valueOf()
                qo.createTimeEnd = qo.createTimeArr[1].valueOf()
                delete qo.createTimeArr;
            }
        }

        const payload = {
            ...qo,
            ...PageUtil.toDto(pagination)
        }

        send(URL.adminQuery, payload).then((resp) => {
            const httpCode = resp.data.httpCode;
            if (httpCode === 200) {
                const data = resp.data.data;
                this.setState(
                    {
                        data: data.records.map((item: { key: number, id: number }) => {
                                return {
                                    ...item,
                                    key: randomString()
                                }
                            }
                        ),
                        pagination: PageUtil.toPagination(data),
                        loading: false
                    }
                );
            } else Handler.ofHttpWarn(httpCode)
        }).catch(Handler.ofError)
    }

    handleFetchNicknameLike(keyword: string) {
        send(URL.adminNicknamesAutoComplete, {nicknameLike: keyword}).then((resp) => {
            const httpCode = resp.data.httpCode;
            if (httpCode === 200) {
                const data = resp.data.data;
                this.setState({optionsOfCreateBy: data})
            } else Handler.ofHttpWarn(httpCode)
        }).catch(Handler.ofError)
    }

    /**
     * Description: 重置管理员秘钥.
     * @author <a href="mailto:scorpio.caplike@gmail.com">LiKe</a> @ 2025-05-28 17:39:30
     */
    handleSecretReset() {
        this.setState({loading: true}, () => {
            const id = this.state.id
            this.secretResettingFormRef.current?.validateFields()
                .then(
                    values => {
                        send(URL.resetSecret, {
                            id: id,
                            newSecret: values.secret
                        }).then(resp => {
                            if (resp.data.httpCode === 200) {
                                message.success('操作成功')
                                    .then(
                                        () => this.setState(
                                            {secretResettingModalVisible: false},
                                            () => this.setState({loading: false}, () => this.secretResettingFormRef.current?.resetFields())
                                        )
                                    )
                            } else Handler.ofError(resp.data.httpCode)
                        }).catch(Handler.ofError)
                    }
                )
                .catch(info => console.log('校验失败:', info))
        })
    }

    handleAdd() {
        this.setState({loading: true}, () => {
            this.adminAddingFormRef.current?.validateFields()
                .then(values => {
                    delete values.confirm
                    send(URL.add, {...values}).then(resp => {
                        if (resp.data.httpCode === 200) {
                            message.success('操作成功')
                                .then(
                                    () => this.setState(
                                        {adminAddingModalVisible: false},
                                        () => this.setState({loading: false}, () => {
                                            this.adminAddingFormRef.current?.resetFields()
                                            this.handleFetch()
                                        })
                                    )
                                )
                        } else Handler.ofError(resp.data.httpCode)
                    }).catch(Handler.ofError)
                })
                .catch(info => console.log('校验失败:', info))
        })
    }

    handleModify() {
        this.setState({loading: true}, () => {
            this.adminModifyingFormRef.current?.validateFields()
                .then(values => {
                    values.id = this.state.id
                    send(URL.modify, {...values}).then(resp => {
                        if (resp.data.httpCode === 200) {
                            message.success('操作成功')
                                .then(
                                    () => this.setState(
                                        {adminModifyingModalVisible: false},
                                        () => this.setState({loading: false}, () => {
                                            this.adminModifyingFormRef.current?.resetFields()
                                            this.handleFetch()
                                        })
                                    )
                                )
                        } else Handler.ofError(resp.data.httpCode)
                    }).catch(Handler.ofError)
                })
                .catch(info => console.log('校验失败:', info))
        })
    }

    /**
     * Description: 删除管理员.
     * @author <a href="mailto:scorpio.caplike@gmail.com">LiKe</a> @ 2025-05-28 17:44:26
     */
    handleDelete(record: Data) {
        send(URL.delete, null, [record.id]).then((resp) => {
            const httpCode = resp.data.httpCode;
            if (httpCode === 200) {
                message.success('操作成功').then(_ => this.handleFetch())
            } else Handler.ofHttpWarn(httpCode)
        }).catch(Handler.ofError)
    }

    render() {
        const {
            data, pagination, loading,
            secretResettingModalVisible, adminAddingModalVisible, adminModifyingModalVisible,
        } = this.state;

        if (!isAdmin()) {
            this.columns = this.columns.filter(column => column.key !== 'ops')
        }

        return (
            <>
                <Form ref={this.searchFormRef} onFinish={(qo) => this.handleFetch(qo)} className="queryForm">
                    <Row gutter={24}>
                        <Col span={8}>
                            <Form.Item label="管理员昵称" name="nickNameLike">
                                <AutoComplete onSearch={(keyword) => this.handleFetchNicknameLike(keyword)} options={this.state.optionsOfCreateBy} placeholder="请输入关键字"/>
                            </Form.Item>
                        </Col>
                    </Row>
                    <Row gutter={24}>
                        <Col span={24}>
                            <Space size={"middle"} style={{float: "right"}}>
                                <Button icon={<LazyIcon iconName="ClearOutlined"/>} htmlType="button" onClick={() => this.searchFormRef.current?.resetFields()}>重置</Button>
                                <Button icon={<LazyIcon iconName="SearchOutlined"/>} type="primary" htmlType="submit">查询</Button>
                                <Divider type="vertical"/>
                                <Button icon={<LazyIcon iconName="Plus"/>} type="default" onClick={() => this.setState({adminAddingModalVisible: true})}>新增管理员</Button>
                            </Space>
                        </Col>
                    </Row>
                </Form>
                <Table
                    footer={() => `总共 ${this.state.pagination.total} 条数据`}
                    loading={loading} columns={this.columns} pagination={pagination} dataSource={data} onChange={(pagination) => this.handleFetch(undefined, pagination)}></Table>

                <Modal title={"新增管理员"} open={adminAddingModalVisible} centered keyboard width={"35%"}
                       onOk={() => this.handleAdd()} okText={"新增"}
                       onCancel={() => this.setState({adminAddingModalVisible: false})} cancelText={"取消"}>
                    <Spin spinning={loading}>
                        <Form ref={this.adminAddingFormRef} layout={"vertical"}>
                            <Form.Item name="name" label="登录名" rules={[{required: true, message: '请输入登录名'}, {min: 2, max: 10, message: '长度应为 2-10 位'}, {pattern: /^[A-Za-z]+$/, message: '只能输入英文字母'}]}
                                       hasFeedback>
                                <Input></Input>
                            </Form.Item>
                            <Form.Item name="nickname" label="昵称" rules={[{required: true, message: '请输入昵称'}, {min: 2, max: 10, message: '长度至少为 2-10 位'}]} hasFeedback>
                                <Input></Input>
                            </Form.Item>
                            <Form.Item name="secret" label="密码" rules={[{required: true, message: '请输入密码'}, {min: 5, max: 10, message: '长度应为 5-10 位'}]} hasFeedback>
                                <Input.Password/>
                            </Form.Item>
                            <Form.Item name="confirm" label="重复密码" dependencies={['secret']} hasFeedback
                                       rules={[
                                           {required: true, message: '请再次输入密码'},
                                           ({getFieldValue}) => ({
                                               validator(_, value) {
                                                   if (!value || getFieldValue('secret') === value) {
                                                       return Promise.resolve();
                                                   }
                                                   return Promise.reject(new Error('两次输入的密码不一致'));
                                               },
                                           }),
                                       ]}
                            >
                                <Input.Password/>
                            </Form.Item>
                        </Form>
                    </Spin>
                </Modal>

                <Modal title={"修改"} open={adminModifyingModalVisible} centered keyboard width={"35%"}
                       onOk={() => this.handleModify()} okText={"修改"}
                       onCancel={() => this.setState({adminModifyingModalVisible: false})} cancelText={"取消"}>
                    <Spin spinning={loading}>
                        <Form ref={this.adminModifyingFormRef} layout={"vertical"} initialValues={{nickname: this.state.nickname}}>
                            <Form.Item label="登录名" hasFeedback>
                                <Input disabled defaultValue={this.state.name}></Input>
                            </Form.Item>
                            <Form.Item name="nickname" label="昵称" rules={[{required: true, message: '请输入昵称'}, {min: 2, max: 10, message: '长度至少为 2-10 位'}]} hasFeedback>
                                <Input></Input>
                            </Form.Item>
                        </Form>
                    </Spin>
                </Modal>

                <Modal title={"重置密码"} open={secretResettingModalVisible} centered keyboard width={"35%"}
                       onOk={() => this.handleSecretReset()} okText={"确认"}
                       onCancel={() => this.setState({secretResettingModalVisible: false})} cancelText={"取消"}>
                    <Spin spinning={loading}>
                        <Form ref={this.secretResettingFormRef} layout={"vertical"}>
                            <Form.Item name="secret" label="密码" rules={[{required: true, message: '请输入密码'}, {min: 5, message: '长度至少为 5 位'}]} hasFeedback>
                                <Input.Password/>
                            </Form.Item>
                            <Form.Item name="confirm" label="重复密码" dependencies={['secret']} hasFeedback
                                       rules={[
                                           {required: true, message: '请再次输入密码'},
                                           ({getFieldValue}) => ({
                                               validator(_, value) {
                                                   if (!value || getFieldValue('secret') === value) {
                                                       return Promise.resolve();
                                                   }
                                                   return Promise.reject(new Error('两次输入的密码不一致'));
                                               },
                                           }),
                                       ]}
                            >
                                <Input.Password/>
                            </Form.Item>
                        </Form>
                    </Spin>
                </Modal>
            </>
        )
    }
}

export default Admin;
